package org.cgc.obj;

import java.util.Date;
import java.util.List;
import java.util.ListIterator;
import java.util.Random;

public class Graph {
	
	private int[] verts;
	private boolean[][] edges;
	
	public Graph(int size) {
		verts = new int[size];
		edges = new boolean[size][];
		for(int i = 0; i < size; i++)
			edges[i] = new boolean[size];
	}
	
	public Graph(int size, int density) {
		verts = new int[size];
		edges = new boolean[size][];
		for(int i = 0; i < size; i++)
			edges[i] = new boolean[size];
		
		Random r = new Random(new Date().getTime());
		
		for(int i = 0; i < size; i++) {
			verts[i] = 0;
			for(int j = i+1; j < size; j++) {
				if(r.nextInt(100) < density) {
					edges[i][j] = true;
					edges[j][i] = true;
				}
				else {
					edges[i][j] = false;
					edges[j][i] = false;
				}
			}
		}
	}
	
	public Graph(boolean[][] edges) {
		this.verts = new int[edges.length];
		this.edges = new boolean[edges.length][];
		for(int i = 0; i < edges.length; i++)
			this.edges[i] = new boolean[edges.length];
		
		for(int i = 0; i < edges.length; i++) {
			verts[i] = 0;
			for(int j = i+1; j < edges.length; j++) {
				this.edges[i][j] = edges[i][j];
				this.edges[j][i] = edges[j][i];
			}
		}
	}
	
	public void copyTo(Graph g) {
		g.verts = new int[verts.length];
		g.edges = new boolean[edges.length][edges.length];
		
		for(int i = 0; i < edges.length; i++) {
			g.verts[i] = verts[i];
			for(int j = 0; j < edges.length; j++) {
				g.edges[i][j] = edges[i][j];
			}
		}
	}
	
	public int getColor(int i) {
		return verts[i];
	}
	
	public void setColor(int i, int color) {
		verts[i] = color;
	}
	
	public int getVertNumber() {
		return verts.length;
	}
	
	public boolean isEdge(int i, int j) {
		return edges[i][j];
	}
	
	public int getMaxDeg() {
		int max = 0;
		for(int i = 0; i < verts.length; i++) {
			if(getDeg(i) > max) max = getDeg(i);
		}
		return max;
	}
	
	public int getDeg(int i) {
		int deg = 0;
		for(int k = 0; k < verts.length; k++) {
			if(isEdge(i, k)) deg++;
		}
		return deg;
	}
	
	public void addVertex() {
		boolean[][] tempEdges = new boolean[edges.length+1][edges.length+1];
		int[] tempVerts = new int[verts.length+1];
		
		for(int i = 0; i < verts.length; i++) {
			tempVerts[i] = verts[i];
			for(int j = 0; j < verts.length; j++) {
				tempEdges[i][j] = edges[i][j];
			}
		}
		edges = tempEdges;
		verts = tempVerts;
	}
	
	public void delVertices(List<Integer> selected) {
		boolean[][] tempEdges = 
			new boolean[edges.length-selected.size()][edges.length-selected.size()];
		int[] tempVerts = new int[verts.length-selected.size()];
		
		int k = 0;
		for(int i = 0; i < verts.length; i++) {
			boolean deleted = false;
			ListIterator<Integer> it = selected.listIterator();
			while(it.hasNext()) {
				int n = it.next().intValue();
				if(i == n) {
					deleted = true;
					break;
				}
			}
			int l = 0;
			for(int j = i+1; j < verts.length; j++) {
				boolean deleted2 = false;
				ListIterator<Integer> it2 = selected.listIterator();
				while(it2.hasNext()) {
					int n = it2.next().intValue();
					if(j == n) {
						deleted2 = true;
						break;
					}
				}
				if(!deleted2) {
					tempEdges[k][l] = edges[i][j];
					tempEdges[l][k] = edges[j][i];
					l++;
				}
				
			}
			if(!deleted) {
				tempVerts[k] = verts[i];
				k++;
			}
		}
		verts = tempVerts;
		edges = tempEdges;
	}
	
	public void setEdges(List<Integer> selected, boolean edge) {
		ListIterator<Integer> it = selected.listIterator();
		while(it.hasNext()) {
			int i = it.next();
			ListIterator<Integer> it2 = selected.listIterator(it.previousIndex());
			while(it2.hasNext()) {
				int j = it2.next().intValue();
				edges[i][j] = edge;
				edges[j][i] = edge;
			}
		}
	}
}
